<?php
  class Mysql{
      private $host;
      private $username;
      private $password;
      private $dbname;
      private $port;
      private $db;
      private static $instance;
      
      private function __construct($host,$username,$password,$dbname,$port){
          $this->host = $host;
          $this->username = $username;
          $this->password = $password;
          $this->dbname = $dbname;
          $this->port = $port;
          //单例模式，自动连接数据库
          $this->connect();
      }
      
      private function __clone(){
      }
      
      /**
      * 单例模式，只能调用一个对象
      * 
      * @param mixed $host
      * @param mixed $username
      * @param mixed $password
      * @param mixed $dbname
      * @param mixed $port
      * @return Mysql
      */
      public static function getInstance($host,$username,$password,$dbname,$port){
          if(!(self::$instance instanceof self)){
              self::$instance = new self($host,$username,$password,$dbname,$port); 
          }
          return self::$instance;
      }
      
      /**
      * 数据库连接
      * 
      */
      private function connect(){
          global $log;
          $this->db = @mysqli_connect($this->host,$this->username,$this->password,$this->dbname,$this->port);
          $log->logInfo("[SQL]连接数据库");
          if(!$this->db){
              $message = mysqli_connect_errno().":".mysqli_connect_error();
              $log->logError("[ERROR]$message");
              return false;
          }
          else{
              //指定编码格式 
              mysqli_query($this->db,"set names utf8");
              return true; 
          }
      }
      
      /**
      * 获取数据库版本
      * 
      */
      public function getVersion(){
          return mysqli_get_server_info($this->db);
      }
      
      /**
      * 得到数据库大小
      * 
      */
      public function getMysqlSize(){
          $sql = 'show table status';
          $dbsize=0;
          $array = $this->query($sql);
          if(is_array($array)){
              foreach($array as $table){
                  $dbsize += $table['Data_length'] + $table['Index_length'];
              }
          }
          return $dbsize;
      }
      
      /**
      * 以数组形式返回多条数据
      * 
      * @param mixed $sql
      * @return mixed
      */
      public function query($sql){
          global $log;
          $log->logInfo("[SQL]$sql");
          $result = mysqli_query($this->db,$sql);
          if($result==false){
              $message = mysqli_error($this->db);
              $log->logError("[ERROR]$message");
              return false;
          }
          else{
              $result_array = array();
              while($array = mysqli_fetch_array($result)){
                  $result_array[] = $array;
              }
              $this->free_result($result);
              return $result_array;
          }
      }
      
      /**
      * 执行sql语句
      * 
      * @param mixed $sql
      */
      public function execute($sql){
          global $log;
          $log->logInfo("[SQL]$sql");
          if(!mysqli_query($this->db,$sql)){
              $message = mysqli_error($this->db);
              $log->logError("[ERROR]$message");
              return false;
          }
          else{
              return true;
          }            
      }
      
      /**
      * 释放result
      * 
      * @param mixed $result
      * @return void
      */
      private function free_result($result){
          return mysqli_free_result($result);
      }
      
      /**
      * 关闭数据库连接
      * 
      */
      public function close(){
          global $log;
          $log->logInfo("[SQL]关闭数据库连接");
          return mysqli_close($this->db);
      }
      
      /**
      * 备份数据库
      * 
      * @param bool $tables
      */
      public function backup($tables = '*'){
          if($tables == '*'){
              $tables = array();
              $result = $this->query('SHOW TABLES');
              foreach($result as $row){
                  $tables[] = $row[0];
              }
          }
          else{
              $tables = is_array($tables) ? $tables : explode(',',$tables);
          }
          
          //cycle through
          foreach($tables as $table){
              $result = mysqli_query($this->db,'SELECT * FROM '.$table);
              $num_fields = mysqli_num_fields($result);
              $return.= 'DROP TABLE IF EXISTS '.$table.';';
              $row2 = mysqli_fetch_row(mysqli_query($this->db,'SHOW CREATE TABLE '.$table));
              $return.= "\n\n".$row2[1].";\n\n";
              for ($i = 0; $i < $num_fields; $i++) {
                  while($row = mysqli_fetch_row($result)){
                      $return.= 'INSERT INTO '.$table.' VALUES(';
                      for($j=0; $j<$num_fields; $j++){
                          $row[$j] = addslashes($row[$j]);
                          $row[$j] = ereg_replace("\n","\\n",$row[$j]);
                          if(isset($row[$j])){
                              $return.= '"'.$row[$j].'"' ;
                          }
                          else{
                              $return.= '""';
                          }
                          if($j<($num_fields-1)){
                              $return.= ',';
                          }
                      }
                      $return.= ");\n";
                  }
              }
              $return.="\n\n\n";
          }
          
          //save file
          $handle = fopen(dirname(__FILE__).'/../bak/talking-'.date('YmdHis').'.sql','w+');
          fwrite($handle,$return);
          fclose($handle);
      }
      
      /**
      * 还原数据库
      * 
      * @param mixed $file
      */
      public function restore($file){
          if(file_exists($file)){
              $flag = true;//用来标记sql语句是否执行成功，true为执行成功，false为执行错误
              $lines = file($file);
              foreach($lines as $line){
                  if (substr($line, 0, 2) == '--' || $line == '') continue;
                  $templine .= $line;
                  if (substr(trim($line), -1, 1) == ';'){
                      if(!$this->execute($templine)){
                          $flag = false;
                          break;
                      }
                      $templine = '';
                  }
              }
              return $flag;
          }
          else{
              return false;
          }       
      }
  }
?>
